<script lang="js" setup name="DisplayerArea">
import { ref, onMounted, computed, reactive, watch, nextTick, getCurrentInstance, onUnmounted, watchEffect } from "vue";
import Displayer from "../components/Displayer.vue";
import { useAppStore } from "../stores/appStore";
import { storeToRefs } from "pinia";
import { useArchiveStore } from "../stores/archive";
import { setReferenceSource, addImageSliceSync, removeImageSliceSync, updateToolBindings } from "../cornerstone3D/initTools";
import DcmTagsWnd from "./DcmTagsWnd.vue";
import SearchPACS from "./SearchPACS.vue";

const { proxy } = getCurrentInstance()
const archiveStore = useArchiveStore();
const { currentStudy, seriesList } = storeToRefs(archiveStore);

const appStore = useAppStore();
const { layout, pageSize, currentDisplayer } = storeToRefs(appStore);

const dispRefs = reactive([]);
const selected = [];
const domWidth = ref(0);
const dcmTagsWnd = ref(null);
const pacsWnd = ref(null);


const containerStyle = computed(() => {
    return {
        gridTemplateColumns: repeat(layout.value.col, "1fr"),
        gridTemplateRows: repeat(layout.value.row, "1fr"),
        height: "100%"
    };
});

const repeat = (n, s) => {
    let dst = "";
    for (let i = 0; i < n; i++) {
        dst += s + " ";
    }
    return dst;
};

const getDispRef = (el, pos) => {
    if (el) {
        dispRefs[pos] = el;
    }
};

const setLayout = (row, col) => {
    layout.value.col = col;
    layout.value.row = row;

    nextTick(() => {
        dispRefs.length = row * col;
    });

    selected.length = 0;

};

const onSelected = ({ pos }) => {
    const idx = selected.indexOf(pos);
    if (idx > -1) {
        return;
    }
    selected.length = 0;
    selected.push(pos);

    for (let i = 0; i < dispRefs.length; i++) {
        if (i == pos) {
            dispRefs[i].setSelected(true);
            currentDisplayer.value = dispRefs[i];
        } else {
            dispRefs[i].setSelected(false);
        }
    }

    if (dispRefs[pos].isLoaded()) {
        setReferenceSource(dispRefs[pos].getViewportId());
    }
    // console.log("selected:", selected);
};

watchEffect(() => {
    const { window, zoom, pan, scroll, measure, measureType } = appStore.toolBindings;
    console.log("toolBindings changed:", window, zoom, pan, scroll, measure, measureType);

    // 智能工具绑定更新策略：
    // 总是更新所有工具绑定，但根据测量工具状态智能处理窗口调窗工具
    updateToolBindings(window, zoom, pan, scroll, measure, measureType);
});

watch(currentStudy, (study) => {
    // console.log("currentStudy changed:", seriesList.value);
    // setTimeout(() => {
    //     displayAuto();
    // }, 100);
})

watch(layout, (lo) => {
    setLayout(lo.row, lo.col);
}, { deep: true });

watch(()=>appStore.syncOperation.syncRoll, (val) => {
    console.log("syncRoll changed:", val);
    if (val) {
        for (let i = 0; i < dispRefs.length; i++) {
            const disp = dispRefs[i];
            addImageSliceSync(disp.getViewportId());
        }
    } else {
        for (let i = 0; i < dispRefs.length; i++) {
            const disp = dispRefs[i];
            removeImageSliceSync(disp.getViewportId());
        }
    }
});

const setWidth = (width) => {
    domWidth.value = width;
};

const calcLayout = (count) => {
    let n = 1;
    if (count > 100) count = 100;

    if (count == 1) {
        return { row: 1, col: 1 };
    }

    if (count == 2) {
        return { row: 1, col: 2 };
    }

    // 移动端限制最大为2x2布局
    if (count >= 3) {
        return { row: 2, col: 2 };
    }

    if (count < 4) count = 4;

    while (n * n < count) {
        n++;
    }

    let r = 1,
        c = 1;
    if (n * (n - 1) >= count) {
        r = n;
        c = n - 1;
    } else {
        r = c = n;
    }

    // 移动端限制最大为2x2
    if (r > 2) r = 2;
    if (c > 2) c = 2;

    return { row: r, col: c };
}

const displayAuto = () => {
    // if (!currentStudy.value) return;
    const count = seriesList.value.length;
    const lo = calcLayout(count);
    layout.value.col = lo.col;
    layout.value.row = lo.row;
    setLayout(lo.row, lo.col);

    nextTick(() => {
        const { col, row } = layout.value;
        const pageSize = Math.min(count, col * row);

        // console.log("displayAuto, count:", count, "pageSize:", pageSize);
        for(let i=0; i<pageSize; i++) {
            const disp = dispRefs[i];
            const series = currentStudy.value.seriesList[i];
            disp.load(series, 0, true);
        }
    });
};

const clear = () => {
    console.log("clear dispRefs.length:", dispRefs.length);
    for (let i = 0; i < dispRefs.length; i++) {
        dispRefs[i].clear();
    }
};

const removeSelectedViewportMeasures = () => {
    console.log("removeSelectedViewportMeasures", selected);
    selected.forEach(pos => {
        const disp = dispRefs[pos];
        disp.removeAllMeasures();
    });
}

const setViewportProperties = (props) => {
    selected.forEach(pos => {
        const disp = dispRefs[pos];
        disp.setProperties(props);
    });
};

const setViewportColorMap = (colorMap) => {
    selected.forEach(pos => {
        const disp = dispRefs[pos];
        disp.setColorMap(colorMap);
    });
};

const resetViewportCamera = () => {
    selected.forEach(pos => {
        const disp = dispRefs[pos];
        disp.resetCamera();
    });
};

const renderAll = () => {
    console.log("renderAll", dispRefs)
    for (let i = 0; i < dispRefs.length; i++) {
        dispRefs[i].render();
    }
};

const setViewportWindow = (wl, ww) => {
for (let i = 0; i < selected.length; i++) {
        const disp = dispRefs[selected[i]];
        if (wl===0 || ww===0) {
            disp.setDefaultWindow();
        } else {
            disp.setWindow(wl, ww);
        }
    }
}

const setViewportVoiRange = (range) => {
    for (let i = 0; i < selected.length; i++) {
        const disp = dispRefs[selected[i]];
        disp.setVoiRange(range);
    }
}

const getViewportWindow = () => {
    const disp = dispRefs[selected[0]];
    return disp.getWindow();
}

const syncVoiRange = (data) => {
    // console.log("syncVoiRange", data.pos, data.range);
    for (let i = 0; i < dispRefs.length; i++) {
        if (i !== data.pos) {
            const disp = dispRefs[i];
            disp.setVoiRange(data.range);
        }
    }
}

const syncZoom = (data) => {
    // console.log("syncZoom", data.zoom);
    for (let i = 0; i < dispRefs.length; i++) {
        if (i !== data.pos) {
            const disp = dispRefs[i];
            disp.setZoom(data.zoom);
        }
    }
}

const syncPan = (data) => {
    // console.log("syncPan", data.pan);
    for (let i = 0; i < dispRefs.length; i++) {
        if (i !== data.pos) {
            const disp = dispRefs[i];
            disp.setPan(data.pan);
        }
    }
}

const stopAutoPlay = ({pos}) => {
    for (let i = 0; i < dispRefs.length; i++) {
        if (i !== pos) {
            dispRefs[i].stopAutoPlay();
        }
    }
}

const showDcmTagsDialog = async () => {
    // console.log("showDcmTagsWnd");
    if (selected.length>0) {
        const disp = dispRefs[selected[0]];
        const tagList = await disp.getTagList();
        // console.log("showDcmTagsWnd tagList:", tagList);
        dcmTagsWnd.value.show(tagList);
    }
}

const showPacsWnd = () => {
    pacsWnd.value.show();
}

const activateMeasureTool = (toolId) => {
    // 激活测量工具 - 通过更新 store 中的 measureType 来触发 watchEffect
    appStore.toolBindings.measureType = toolId;
    console.log("激活测量工具:", toolId);
}

defineExpose({
    setWidth,
    setLayout,
    displayAuto,
    renderAll,
    clear,
    removeSelectedViewportMeasures,
    setViewportProperties,
    setViewportColorMap,
    resetViewportCamera,
    setViewportWindow,
    getViewportWindow,
    setViewportVoiRange,
    showDcmTagsDialog,
    showPacsWnd,
    activateMeasureTool,
});

onMounted(() => {
	// console.log("DisplayerArea mounted, layout: ", window.config?.defLayout);
	// 移动端默认使用2x2布局
	const { row, col } = window.config?.defLayout || { row: 2, col: 2 };
	layout.value.col = Math.min(col, 2); // 限制最大2列
	layout.value.row = Math.min(row, 2); // 限制最大2行
	setLayout(layout.value.row, layout.value.col);

	proxy.emitter.on("syncWindow", syncVoiRange);
	proxy.emitter.on("syncZoom", syncZoom);
	proxy.emitter.on("syncPan", syncPan);
	proxy.emitter.on("stopAutoPlay", stopAutoPlay);
});

onUnmounted(() => {
    console.log("DisplayerArea unmounted");
    proxy.emitter.off("syncWindow", syncVoiRange);
    proxy.emitter.off("syncZoom", syncZoom);
    proxy.emitter.off("syncPan", syncPan);
    proxy.emitter.off("stopAutoPlay", stopAutoPlay);
});
</script>

<template>
	<div class="displayarea">
		<DcmTagsWnd ref="dcmTagsWnd" />
		<SearchPACS ref="pacsWnd" />
		<div class="container" :style="containerStyle">
			<Displayer
				v-for="(v, idx) in pageSize"
				:key="idx"
				:ref="el => getDispRef(el, idx)"
				:pos="idx"
				@selected="onSelected"
			/>
		</div>
	</div>
</template>

<style lang="scss" scoped>
.displayarea {
	position: relative;
	width: 100%;
	height: 100%;
	overflow: auto;
	background-color: black;

	.container {
		display: grid;
		grid-gap: 1px 1px;
		background-color: black;
		color: #fff;
		width: 100%;
		height: 100%;
	}
}

/* 移动端响应式设计 */
@media (max-width: 768px) {
	.displayarea {
		-webkit-overflow-scrolling: touch;
		scrollbar-width: none; /* Firefox */
		-ms-overflow-style: none; /* IE and Edge */
	}

	.displayarea::-webkit-scrollbar {
		display: none; /* Chrome, Safari, Opera */
	}

	.container {
		grid-gap: 0.5px 0.5px;
	}
}

/* 超小屏幕手机 (320px - 480px) */
@media (max-width: 480px) {
	.container {
		grid-gap: 0.3px 0.3px;
	}
}

/* 平板设备适配 (769px - 1024px) */
@media (min-width: 769px) and (max-width: 1024px) {
	.container {
		grid-gap: 0.8px 0.8px;
	}
}

/* 触摸设备优化 */
@media (hover: none) and (pointer: coarse) {
	.displayarea {
		touch-action: pan-x pan-y;
		scroll-behavior: smooth;
	}
}

/* 横屏模式优化 */
@media (orientation: landscape) and (max-width: 768px) {
	.container {
		grid-gap: 0.4px 0.4px;
	}
}
</style>
